#pragma once
#include <iostream>
#include <utility>
#include "RBtree.hpp"

namespace me
{
    template <typename K, typename V>
    class map
    {
        struct K2V
        {
            const K& operator()(const value_type& kv) const
            {
                return kv.first;
            }
        };
        using value_type = std::pair<const K, V>;
        using rbt = rbtree<K, value_type, K2V>;
        using iterator = typename rbtree<K, value_type, K2V>::iterator;
        using const_iterator = typename rbtree<K, value_type, K2V>::const_iterator;

    public:
        std::pair<iterator, bool> insert(const value_type& kv)
        {
            return _tree.insert(kv);
        }

        V& operator[](const K& key)
        {
            std::pair<iterator, bool> ret = insert({key, V()});
            return ret.first->second;
        }

        iterator begin() { return _tree.begin(); }
        const_iterator begin() const { return _tree.begin(); }
        const_iterator cbegin() const { return _tree.cbegin(); }

        iterator end() { return _tree.end(); }
        const_iterator end() const { return _tree.end(); }
        const_iterator cend() const { return _tree.cend(); }
    private:
        rbt _tree;
    };
}